package com.yingluo.abacus.boot.core.data.hibernate.dao;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.yingluo.abacus.boot.core.data.hibernate.utils.HibernateUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import org.hsqldb.types.BinaryData;


public  class CCBaseDao<T extends java.io.Serializable, PK extends java.io.Serializable> implements ICCDao<T, PK> {
	private Class<T> entityClass;
	public CCBaseDao(SessionFactory factory ,Class<T> boClass) {
		sessionFactory=factory;  
		entityClass = boClass;
	}
	private SessionFactory sessionFactory;
	public Session getSession() { 
		// 事务必须是开启的(Required)，否则获取不到 
		return sessionFactory.getCurrentSession();
	}
	public PK save(T entity) {
		return (PK) getSession().save(entity);
	}

	public void merge(T entity) {
		getSession().merge(entity);
	}

	public void update(T entity) {
		getSession().update(entity);
	}

	public void saveOrUpdate(T entity) {
		getSession().saveOrUpdate(entity);
	}

	public void delete(PK id) {
		getSession().delete(this.get(id));
	}

	public void deleteObject(T entity) {
		getSession().delete(entity); 
	}

	public boolean exists(PK id) {
		return get(id) != null;
	}

	public T load(PK id) {
		return (T) getSession().load(this.entityClass, id);
	}

	public T get(PK id) {
		return (T) getSession().get(this.entityClass, id);
	}

	public PK saveLogic(T entity) throws Exception {
		return this.saveLogic(entity, HibernateUtils.getCurrentLoginId());
	}

	public void mergeLogic(T entity) throws Exception {
		this.mergeLogic(entity, HibernateUtils.getCurrentLoginId());
		
	}

	public void saveOrUpdateLogic(T entity) throws Exception {
		this.saveOrUpdateLogic(entity, HibernateUtils.getCurrentLoginId());
		
	}

	public void deleteLogic(PK id) throws Exception{
		this.deleteLogic(id, HibernateUtils.getCurrentLoginId());
		
	}

	public void deleteObjectLogic(T entity) throws Exception{
		this.deleteObjectLogic(entity, HibernateUtils.getCurrentLoginId());
		
	}

	public boolean existsLogic(T entity) throws Exception{

		if(entity==null){
			throw new Exception("要保存的对像不能为空");
		}
		if(!(entity instanceof ICCEntity)){
			throw new Exception("要操作的对像请继承ICCEntity类");
		}	
		ICCEntity old=(ICCEntity)getSession().get(entityClass,((ICCEntity)entity).getTableId());
		
		 return old!=null&& old.getDeleteLogic();
	}

	public T loadLogic(PK id) throws Exception{
		T entity =this.load(id);
		if(entity!=null){

			if(!(entity instanceof ICCEntity)){
				throw new Exception("要操作的对像请继承ICCEntity类");
			}
			ICCEntity t=(ICCEntity)entity;
			return (!t.getDeleteLogic())?entity:null;
		}
		return null;
	}

	public T getLogic(PK id) throws Exception{
		T entity =this.get(id);
		if(entity!=null){

			if(!(entity instanceof ICCEntity)){
				throw new Exception("要操作的对像请继承ICCEntity类");
			}
			ICCEntity t=(ICCEntity)entity;
			return (!t.getDeleteLogic())?entity:null;
		}
		return null;
	}

	public int countAll() {
		Criteria criteria = createCriteria();
		return Integer.valueOf(criteria.setProjection(Projections.rowCount())
		.uniqueResult().toString());
	}

	public int countAll(Criteria criteria) {
		if(criteria==null)criteria=this.createCriteria();
		return Integer.valueOf(criteria.setProjection(Projections.rowCount()) 
				.uniqueResult().toString());
	}

	public int countAllLogic(Criteria criteria) {
		if(criteria==null)criteria=this.createCriteria();
		criteria.add(Restrictions.eq("deleteLogic", false));
		return countAll(criteria);
	}

	public void deleteAll(Collection<?> entities) {
		if (entities == null) return;
		for (Object entity : entities) {
			getSession().delete(entity);
		}
		
	}

	public void deleteAllLogic(Collection<?> entities) throws Exception {
		if (entities == null) return;
		for (Object entity : entities) {
			this.deleteObjectLogic((T)entity);
		}
	}

	public List<T> list() {
		return createCriteria().list();
	}

	public List<T> list(Criteria criteria) {
		if(criteria==null)criteria=this.createCriteria();
		return criteria.list();
	}

	public List<T> list(DetachedCriteria criteria) { 
		return (List<T>) list(criteria.getExecutableCriteria(getSession()));
	}

	public List<T> list(String orderBy, boolean isAsc) {
		Criteria criteria = createCriteria();
		if (isAsc) {
			criteria.addOrder(Order.asc(orderBy));
		} else {
			criteria.addOrder(Order.desc(orderBy));
		}
		return criteria.list();
	}

	public List<T> list(String propertyName, Object value) {
		Criterion criterion = Restrictions
				.like(propertyName, "%" + value + "%");
				return list(criterion);
	}

	public List<T> list(Criterion criterion) {
		Criteria criteria = createCriteria();
		criteria.add(criterion);
		return criteria.list();
	}

	public List<T> list(Criterion... criterions) {
		return createCriteria(criterions).list();
	}

	public List<T> listLogic(Criteria criteria) { 
        if(criteria==null)criteria=this.createCriteria();
		criteria.add(Restrictions.eq("deleteLogic", false));
		return list(criteria);
	} 

	public List<T> listLogic(Criterion... criterions) {
		return listLogic(createCriteria(criterions));
	}

	public T uniqueResult(String propertyName, Object value) {
		Criterion criterion = Restrictions.eq(propertyName, value);
		return (T) createCriteria(criterion).uniqueResult();
	}

	public T uniqueResult(Criterion... criterions) {
		Criteria criteria = createCriteria(criterions);
		return uniqueResult(criteria);
	}

	public T uniqueResult(Criteria criteria) {
		return (T) criteria.uniqueResult();
	}

	public T uniqueResultLogic(Criterion... criterions) { 
		Criteria criteria = createCriteria(criterions);
		if(criteria==null)criteria=this.createCriteria();
		criteria.add(Restrictions.eq("deleteLogic", false));
		return uniqueResult(criteria);
	}

	public Criteria distinct(Criteria criteria) {
		// 将结果集进行一次封装，封装成DISTINCT_ROOT_ENTITY对象，方便service层代码使用
		criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
		return criteria;
	}

	public void flush() {
		getSession().flush();
		
	}

	public void clear() {
		getSession().clear();
		
	}

	public Criteria createCriteria() { 
		return getSession().createCriteria(entityClass);
	}

	public Criteria createCriteria(Criterion... criterions) {
		Criteria criteria = createCriteria();
		for (Criterion c : criterions) {
			criteria.add(c);
		}
		return criteria;
	}
	

	public List<T> pagedQuery(Criteria criteria, Pagination<T> pagination,
			Criteria addorder) {
		if(addorder==null)addorder=this.createCriteria();
		// 设置起始结果数
		addorder.setFirstResult((pagination.getNowpage().intValue() - 1) * pagination.getPagesize().intValue());
		// 返回的最大结果集
		addorder.setMaxResults(pagination.getPagesize().intValue());
		List<T> list = list(addorder);
		pagination.setAllentities(list);
 
		// count查询
		// 获得查询总数
		if(criteria==null)criteria=this.createCriteria();
		long totalCount = countAll(criteria);
		pagination.setCountrecord(totalCount < 1 ? 0L : totalCount);
		pagination.init();
		return list;
	}

	public List<T> pagedQueryLogic(Criteria criteria, Pagination<T> pagination,
			Criteria addorder) {

		if(criteria==null)criteria=this.createCriteria();

		criteria.add(Restrictions.eq("deleteLogic", false));
		if(addorder==null)addorder=this.createCriteria();
		addorder.add(Restrictions.eq("deleteLogic", false));
		return pagedQuery(criteria,pagination,addorder);
	}

	public List<T> pagedQuery(Criteria criteria, Pagination<T> pagination) { 
		if(criteria==null)criteria=this.createCriteria();
		// 设置起始结果数
		criteria.setFirstResult((pagination.getNowpage().intValue() - 1) * pagination.getPagesize().intValue());
		// 返回的最大结果集
		criteria.setMaxResults(pagination.getPagesize().intValue());
		List<T> list = list(criteria);
		pagination.setAllentities(list);
		/*
		 * 
		 * 
		 * 注：因为finaPage方法改变了查询条件导致countALL方法查询为空， 所以必须重新设置setFirstResult为0
		 * 
		 * 
		 */
		if(pagination.getCountrecord()==null|| pagination.getCountrecord()<=0){

			criteria.setFirstResult(0);
			// count查询
			// 获得查询总数
			long totalCount = countAll(criteria);
			pagination.setCountrecord(totalCount < 1 ? 0L : totalCount);
		}
		pagination.init();
		return list;
	}

	public List<T> pagedQueryLogic(Criteria criteria, Pagination<T> pagination) {

		if(criteria==null)criteria=this.createCriteria();

		criteria.add(Restrictions.eq("deleteLogic", false));
		return pagedQuery(criteria,pagination);
	}

	public List<T> findByHql(String arg0) throws Exception {
		 return getQueryByParams(null, arg0, new Object[] {}).list();
	}

	public List<T> findByHql(String arg0, Object obj) throws Exception {
		return findByHql(arg0, new Object[] {obj});
	}

	public List<T> findByHql(String arg0, Object[] obj) throws Exception {
		 return getQueryByParams(null, arg0, obj).list();
	}

	public List<T> findByHql(String arg0, Map<String, Object> obj) throws Exception {
		return getQueryByParams(null, arg0, obj).list();
	}

	public List<T> findByHql(Class<?> type, String arg0, Map<String, Object> obj) throws Exception {
		return getQueryByParams(type, arg0, obj).list();
	}

	public List<T> findByHql(String arg0, Pagination<T> pagination) throws Exception {
		return findByHql( arg0, null, pagination);
	}

	public List<T> findByHql(String arg0, Object obj, Pagination<T> pagination) throws Exception {
		return findByHql( arg0, obj, pagination);
	}

	public List<T> findByHql(String arg0, Map<String, Object> obj, Pagination<T> pagination) throws Exception {
		return findByHql(null, arg0, obj, pagination);
	}

	public List<T> findByHql(Class<?> type, String arg0, Map<String, Object> obj, Pagination<T> pagination)
			throws Exception {
		List<?> list = this.findByHql("select count(*) " + arg0.substring(arg0.toLowerCase().indexOf("from")), obj);
		Long totalSize = Long.parseLong(list.get(0).toString());// todo bug
																// 可能超过整形最大？
		Long pages = totalSize / pagination.getPagesize() + ((totalSize % pagination.getPagesize()) > 0 ? 1 : 0);
		if (pagination.getNowpage() < 1)
			pagination.setNowpage(1L);
		if (pagination.getNowpage() > pages)
			pagination.setNowpage(pages);
		Query query = this.getQueryByParams(type, arg0, obj);
		List<T> data = query
				.setFirstResult(pagination.getPagesize().intValue() * (pagination.getNowpage().intValue() - 1))
				.setMaxResults(pagination.getPagesize().intValue()).list();

		pagination.init(pagination.getNowpage(), totalSize);
		pagination.setAllentities(data);
		return data;
	}
	private String getLogicWhere(String arg0){
		if(StringUtils.isNotBlank(arg0)){
			String where=" deleteLogic=:deleteLogic ";
			arg0=StringUtils.lowerCase(arg0);
			if(StringUtils.indexOf(arg0, "where")>0){
				arg0=StringUtils.replaceOnce(arg0,  "where", where);
			}else{
				int groupIndex=StringUtils.indexOf(arg0,"group");
				int orderIndex=StringUtils.indexOf(arg0,"order");
				int startIndex=groupIndex>orderIndex?orderIndex:groupIndex;
				if(startIndex>0){
					arg0=where.substring(0, startIndex-1)+where+where.substring(startIndex);
				}
			}
		}
		return arg0;
	}

	public List<?> findByHqlLogic(String arg0) throws Exception {
		
		return this.findByHqlLogic(arg0);
	} 

	public List<?> findByHqlLogic(String arg0, Map<String, Object> obj) throws Exception {
		return this.findByHqlLogic(null,arg0, obj);
	}

	public List<?> findByHqlLogic(Class<?> type, String arg0, Map<String, Object> obj) throws Exception {
		if(obj==null){
			obj=new HashMap<String,Object>();
		}
		obj.put("deleteLogic", false);
		return this.findByHql(type,getLogicWhere(arg0), obj);
	}

	public List<?> findByHqlLogic(String arg0, Pagination<T> pagination) throws Exception {
		return this.findByHqlLogic(arg0,null, pagination);
	} 

	public List<?> findByHqlLogic(String arg0, Map<String, Object> obj, Pagination<T> pagination) throws Exception {
		return this.findByHqlLogic(null,arg0,obj, pagination);
	}

	public List<?> findByHqlLogic(Class<?> type, String arg0, Map<String, Object> obj, Pagination<T> pagination)
			throws Exception {
		if(obj==null){
			obj=new HashMap<String,Object>();
		}
		obj.put("deleteLogic", false);
		return this.findByHql(type,getLogicWhere(arg0),obj, pagination);
	} 
	

	public List<?> findBySql(String arg0) throws Exception {
		return getSqlQueryByParams(null,arg0, new Object[]{}).list();
	}

	public List<?> findBySql(String arg0, Object obj) throws Exception {
		return getSqlQueryByParams(null,arg0, new Object[]{obj}).list();
	}

	public List<?> findBySql(String arg0, Object[] obj) throws Exception {
		return getSqlQueryByParams(null,arg0, obj).list();
	}

	public List<?> findBySql(String arg0, Map<String, Object> obj) throws Exception {
		return getSqlQueryByParams(null,arg0, obj).list();
	}

	public List<?> findBySql(Class<?> type, String arg0, Map<String, Object> obj) throws Exception {
		return getSqlQueryByParams(type,arg0, obj).list();
	}

	public List<?> findBySql(String arg0, Pagination<T> pagination) throws Exception {
		return findBySql(arg0,null,pagination);
	}

	public List<?> findBySql(String arg0, Object obj, Pagination<T> pagination) throws Exception {
		return findBySql(null,arg0,new Object[] {obj},pagination);
	}

	public List<T> findBySql(String arg0, Map<String, Object> obj, Pagination<T> pagination) throws Exception {
		return findBySql(null,arg0,obj,pagination);
	}
	

	public List<T> findBySql(Class<?> type, String arg0, Map<String, Object> obj, Pagination<T> pagination)
			throws Exception {
		List<?> list = this.findBySql("select count(*) " + arg0.substring(arg0.toLowerCase().indexOf("from")), obj);
		Long totalSize = Long.parseLong(list.get(0).toString());

		Long pages = totalSize / pagination.getPagesize() + ((totalSize % pagination.getPagesize()) > 0 ? 1 : 0);
		if (pagination.getNowpage() < 1)
			pagination.setNowpage(1L);
		if (pagination.getNowpage() > pages)
			pagination.setNowpage(pages);
		Query query = this.getSqlQueryByParams(type, arg0, obj);
		List<T> data = query
				.setFirstResult(pagination.getPagesize().intValue() * (pagination.getNowpage().intValue() - 1))
				.setMaxResults(pagination.getPagesize().intValue()).list();

		pagination.init(pagination.getPagesize(), totalSize);
		pagination.setAllentities(data);
		return data;

	}

	public List<?> findBySql(Class<?> type, String arg0, Object[] obj, Pagination<T> pagination) throws Exception {
		List<?> list = this.findBySql("select count(*) " + arg0.substring(arg0.toLowerCase().indexOf("from")),obj);
		Long totalSize = Long.parseLong(list.get(0).toString());

		Long pages = totalSize / pagination.getPagesize() + ((totalSize % pagination.getPagesize()) > 0 ? 1 : 0);
		if (pagination.getNowpage() < 1)
			pagination.setNowpage(1L);
		if (pagination.getNowpage() > pages)
			pagination.setNowpage(pages);
		Query query = this.getSqlQueryByParams(type, arg0, obj);
		List<T> data = query
				.setFirstResult(pagination.getPagesize().intValue() * (pagination.getNowpage().intValue() - 1))
				.setMaxResults(pagination.getPagesize().intValue()).list();

		pagination.init(pagination.getPagesize(), totalSize);
		pagination.setAllentities(data);
		return data;
	}

	public List<?> findBySqlLogic(String arg0) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public List<?> findBySqlLogic(String arg0, Map<String, Object> obj) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public List<?> findBySqlLogic(Class<?> type, String arg0, Map<String, Object> obj) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public List<?> findBySqlLogic(String arg0, Pagination<T> pagination) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public List<?> findBySqlLogic(String arg0, Map<String, Object> obj, Pagination<T> pagination) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public List<?> findBySqlLogic(Class<?> type, String arg0, Map<String, Object> obj, Pagination<T> pagination)
			throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public int excuteByHql(String arg0) throws Exception {
		return getQueryByParams(null,arg0,new Object[]{}).executeUpdate();
	}

	public int excuteByHql(String arg0, Object obj) throws Exception {
		return getQueryByParams(null,arg0,new Object[]{obj}).executeUpdate();
	}

	public int excuteByHql(String arg0, Object[] obj) throws Exception {
		return getQueryByParams(null,arg0,obj).executeUpdate();
	}

	public int excuteByHql(String arg0, Map<String, Object> obj) throws Exception {
		return getQueryByParams(null,arg0,obj).executeUpdate();
	}

	public int excuteBySql(String arg0) throws Exception {
		return getSqlQueryByParams(null,arg0,new Object[]{}).executeUpdate();
	}

	public int excuteBySql(String arg0, Object obj) throws Exception {

		return getSqlQueryByParams(null,arg0,new Object[]{obj}).executeUpdate();
	}

	public int excuteBySql(String arg0, Object[] obj) throws Exception {
		return getSqlQueryByParams(null,arg0,obj).executeUpdate();
	}

	public int excuteBySql(String arg0, Map<String, Object> obj) throws Exception {
		return getSqlQueryByParams(null,arg0,obj).executeUpdate();
	}

	public int callProcedure(String sql) throws Exception {
		return excuteBySql(sql,new Object[]{});
	}

	public int callProcedure(String sql, Object[] obj) throws Exception {
		return excuteBySql(sql,obj);
	}

	public int callProcedure(String sql, Map<String, Object> obj) throws Exception {
		return excuteBySql(sql,obj);
	}

	public Object copyBo(Object orig) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public Object copyPropertiy(Object orig) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public List<?> findByNamedQuery(String queryName) throws Exception {
		return findByNamedQuery(null,queryName);
	}

	public List<?> findByNamedQuery(Class<?> type, String queryName) throws Exception {
		return findByNamedQuery(type,queryName,null);
	}

	public List<?> findByNamedQuery(String queryName, Map<String, ?> params) throws Exception {
		return findByNamedQuery(null,queryName,params);
	}

	public List<?> findByNamedQuery(Class<?> type, String queryName, Map<String, ?> params) throws Exception {
		if(StringUtils.isBlank(queryName)){
			throw new Exception("命名查询名不能为空");
		}
		Query q =this.getSession().getNamedQuery(queryName);
		if(params!=null){
			getNamedQueryByParams(params,q);
		}
		if(type!=null){
			q.setResultTransformer(Transformers.aliasToBean(type));
		}
		return q.list();
	}

	public List<?> findByNamedQuery(String queryName, Pagination<T> pagination) throws Exception {
		return findByNamedQuery(null,queryName,null,pagination);
	}

	public List<?> findByNamedQuery(String queryName, Map<String, ?> params, Pagination<T> pagination)
			throws Exception {
		return findByNamedQuery(null,queryName,params,pagination);
	}

	public List<T> findByNamedQuery(Class<?> type, String queryName, Map<String, ?> params,
			Pagination<T> pagination)
			throws Exception {
		Query q =getSession().getNamedQuery(queryName+"_count"); 

		if(params!=null){
			getNamedQueryByParams(params,q);
		}
		List<Object> ls =(List<Object>)q.list();
		Long totalSize = ls!=null&ls.size()>0?Long.valueOf(ls.get(0).toString()):0;//todo bug 可能超过整形最大？
		
        Long pages = totalSize / pagination.getPagesize() + ((totalSize % pagination.getPagesize()) > 0 ? 1 : 0);
        if (pagination.getNowpage() < 1)
        	pagination.setNowpage(1L);
        if (pagination.getNowpage()  > pages)
        	pagination.setNowpage(pages);
        if(type!=null){
			q.setResultTransformer(Transformers.aliasToBean(type));
		}
        List<T> data =q.setFirstResult(pagination.getPagesize().intValue() 
        								* (pagination.getNowpage().intValue()  - 1))
    			.setMaxResults(pagination.getPagesize().intValue()).list();
        pagination.init(pagination.getPagesize() , totalSize);
        pagination.setAllentities(data);
		return data;
	}
 

	 
	private   Query getSqlQueryByParams(  Class<?> type,final String arg0, final Object[] obj){
		Query query = getSession().createSQLQuery(arg0);
		if(type!=null){
			query.setResultTransformer(Transformers.aliasToBean(type));
		}
		if (obj != null) {
            for (int i = 0; i < obj.length; i++) {
                query.setParameter(i, obj[i]);
            }
        }
		return query;
	}	
	private   Query getSqlQueryByParams(   Class<?>type,final String arg0, final Map<String ,Object> obj){
		Query query = getSession().createSQLQuery(arg0);
		if(type!=null){
			query.setResultTransformer(Transformers.aliasToBean(type));
		}
		if(obj!=null){
			for (Map.Entry<String, Object> entry : obj.entrySet()) {
				 query.setParameter(entry.getKey(), entry.getValue());
			}
			
		}
		return query;
	}
	
	private Query getQueryByParams(Class type,final String arg0, final Object[] obj){
		Session session= getSession();
		Query query =session.createQuery(arg0);

		if(type!=null){
			query.setResultTransformer(Transformers.aliasToBean(type));
		}
		if (obj != null) {
            for (int i = 0; i < obj.length; i++) {
                query.setParameter(i, obj[i]);
            }
        }
		return query;
	}
	private Query getQueryByParams(Class<?> type,final String arg0, final Map<String ,Object> obj){
		Query query = getSession().createQuery(arg0);

		if(type!=null){
			query.setResultTransformer(Transformers.aliasToBean(type));
		}
		if(obj!=null){
			for (Map.Entry<String, Object> entry : obj.entrySet()) {
				 query.setParameter(entry.getKey(), entry.getValue());
			}
			
		}
		return query;
		
	}
	private void getNamedQueryByParams(final Map<String ,?> params,Query q) throws Exception{
		for (Map.Entry<String, ?> entry : params.entrySet()) {
			Object value=entry.getValue();
			if(value instanceof Date){
				q.setDate(entry.getKey(), value==null?null:(Date)value);
			}else if(value instanceof Boolean){
				q.setBoolean(entry.getKey(),  value==null?null:(Boolean)value);
			}else if(value instanceof Calendar){
				q.setCalendar(entry.getKey(),  value==null?null:(Calendar)value);
			}else if(value instanceof Double){
				q.setDouble(entry.getKey(),  value==null?null:(Double)value);
			}else if(value instanceof Float){
				q.setFloat(entry.getKey(),  value==null?null:(Float)value);
			}else if(value instanceof String){
				q.setString(entry.getKey(),  value==null?null:(String)value);
			}else if(value instanceof Integer){
				q.setInteger(entry.getKey(),  value==null?null:(Integer)value);
			}else if(value instanceof Long){
				q.setLong(entry.getKey(),  value==null?null:(Long)value);
			}else if(value instanceof BigDecimal){
				q.setBigDecimal(entry.getKey(),  value==null?null:(BigDecimal)value);
			}else if(value instanceof BigInteger){
				q.setBigInteger(entry.getKey(),  value==null?null:(BigInteger)value);
			}else if(value instanceof BinaryData){ 
				q.setBinary(entry.getKey(),  value==null?null:((BinaryData)value).getBytes());
			}else{
				throw new Exception("命名查询参数类型未知");
			}
		}

	}

	public PK saveLogic(T entity, String loginid) throws Exception {
		return this.save(logicEntity(entity,loginid));
	}
	private T logicEntity(T entity, String loginid) throws Exception{
		if(entity==null){
			throw new Exception("要保存的对像不能为空");
		}
		if(!(entity instanceof ICCEntity)){
			throw new Exception("要操作的对像请继承ICCEntity类");
		}	
		if(StringUtils.isNotBlank(loginid)){
			((ICCEntity)entity).setUpdateLoginId(loginid);
			((ICCEntity)entity).setCreateLoginId(loginid);
		}
		Date thisDay=new Date(System.currentTimeMillis());
		((ICCEntity)entity).setCreateDate(thisDay);
		((ICCEntity)entity).setDeleteLogic(false);
		((ICCEntity)entity).setUpdateDate(thisDay);
		return entity;
	}
	private T updatelogicEntity(T entity, String loginid) throws Exception{
		if(entity==null){
			throw new Exception("要保存的对像不能为空");
		}
		if(!(entity instanceof ICCEntity)){
			throw new Exception("要操作的对像请继承ICCEntity类");
		}	
		
		ICCEntity t=(ICCEntity)entity;
		ICCEntity old=(ICCEntity)getSession().get(entityClass, t.getTableId());
		if(old==null || old.getDeleteLogic()){
			throw new Exception("要操作的对像已不存在");
		}
		clear((T)old); 
		if(t.getUpdateDate()==null || t.getUpdateDate().before(old.getUpdateDate())){
			throw new Exception("要操作的对像比较旧");
		}
		
		if(StringUtils.isNotBlank(loginid)){
			((ICCEntity)entity).setUpdateLoginId(loginid); 
		}
		Date thisDay=new Date(System.currentTimeMillis());  
		((ICCEntity)entity).setUpdateDate(thisDay);
		this.update(entity);
		return entity;
	}

	public void mergeLogic(T entity, String loginid) throws Exception   {
		this.merge(logicEntity(entity,loginid));
	}

	public void saveOrUpdateLogic(T entity, String loginid) throws Exception {
		this.saveOrUpdate(updatelogicEntity(entity,loginid));
		
	}

	public void deleteLogic(PK id, String loginid) throws Exception {
		T entity=this.getLogic(id);
		this.deleteObjectLogic(entity, loginid);
	}

	public void deleteObjectLogic(T entity, String loginid) throws Exception {
		if(entity==null){
			throw new Exception("要保存的对像不能为空");
		}
		if(!(entity instanceof ICCEntity)){
			throw new Exception("要操作的对像请继承ICCEntity类");
		}
		ICCEntity t=(ICCEntity) entity;
		t.setDeleteLogic(true);
		t.setDeleteDate(new Date(System.currentTimeMillis()));
		t.setDeleteLoginId(loginid);

		this.update(entity);
		
	}

	public void clear(T ob) {
		getSession().evict(ob); 
		
	}

}